/**
 * 执行动画的函数
 * 参数：
 *  obj： 要执行动画的对象
 *  attr: 要执行动画的样式, 比如 top left with
 *  target：执行动画的目标位置
 *  speed：移动的速度
 *  callback: 回调函数，这个函数将会在动画执行完成以后执行
 *
 */
function move(obj, attr, target, speed, callback) {
    clearInterval(obj.timer);

    // 获取元素目前的位置
    var current = parseInt(getStyle(obj, attr));

    /**
     * 如果从左向右移动 speed 为正值
     * 如果从右向左移动，speed为负值
     */
    if(current > target) {
        speed = -speed;
    }

    /**
     * 向执行动画的对象中添加一个属性，用来保存它自己的定时器标识
     */
    obj.timer = setInterval(function () {
        var oldValue = parseInt(getStyle(obj, attr));

        var newValue = oldValue + speed;

        /**
         *  向左移动时，需要判断newValue是否小于target
         *  向右移动时，需要判断newValue是否大于target
         */
        if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
            newValue = target;
        }
        obj.style[attr] = newValue + "px";
        if(newValue == target) {
            clearInterval(obj.timer);

            // 动画执行完毕，调用回调函数
            callback && callback();
        }
    }, 30);
}

/**
 * 用来获取指定元素的当前样式
 * @param obj 要获取样式的元素
 * @param name 要获取的样式名
 * @returns {*}
 *
 * ps: 在IE浏览器中如果没有指定样式值，则可能获取到的是auto
 */
function getStyle(obj, name) {
    if(window.getComputedStyle) {
        return getComputedStyle(obj, null)[name]; // 正常浏览器的方式
    } else {
        return obj.currentStyle[name]; // IE8的方式
    }
}

/**
 * 定义一个函数，用来向一个元素中添加指定的class属性值
 * @param obj 要添加class属性的元素
 * @param cn 要添加的class值
 */
function addClass(obj, cn) {

    if(!hasClass(obj, cn)) {
        obj.className += " " + cn;
    }
}

/**
 * 定义一个函数，判断该函数中是否含有指定的class属性值, 如果有该class，则返回true，否则返回false
 * @param obj 要添加class属性的元素
 * @param cn 要添加的class值
 */
function hasClass(obj, cn) {
    // 判断obj中有没有cn class
    var reg = new RegExp("\\b" + cn + "\\b"); // 使用正则表达式判断
    return reg.test(obj.className);
}

/**
 * 定义一个函数，删除指定元素的class属性
 * @param obj 要添加class属性的元素
 * @param cn 要添加的class值
 */
function removeClass(obj, cn) {
    var reg = new RegExp("\\b" + cn + "\\b"); // 使用正则表达式判断

    // 删除class
    obj.className = obj.className.replace(reg, "");
}

/**
 * 定义一个函数，用来切换元素中的类，如果元素中具有该类，则进行删除，如果元素中没有该类，则进行添加
 * @param obj 要添加class属性的元素
 * @param cn 要添加的class值
 */
function toggleClass(obj, cn) {
    if(hasClass(obj, cn)) {
        removeClass(obj, cn);
    } else {
        addClass(obj, cn);
    }
}